package compiler

import (
	"context"
	"fmt"

	"github.com/go-playground/validator/v10"
	"gitverse.ru/dlc/similarity-compiler/internal/dto/service"
	"gitverse.ru/dlc/similarity-compiler/pkg/api/grpc/proto"
	"gitverse.ru/dlc/similarity-compiler/pkg/errors"
)

type Compiler interface {
	Compile(ctx context.Context, code []byte) ([]byte, error)
}

type Deps struct {
	LuaJITCompiler Compiler `validate:"required"`
}

type Service struct {
	luaJITCompiler Compiler
}

func New(deps Deps) (*Service, errors.Error) {
	if err := validator.New().Struct(deps); err != nil {
		return nil, errors.NewWithError(fmt.Errorf("validate deps: %w", err), errors.ErrInternalError)
	}

	return &Service{
		luaJITCompiler: deps.LuaJITCompiler,
	}, nil
}

func (s *Service) Compile(ctx context.Context, in service.CompileScriptInput) (*service.CompileScriptOutput, errors.Error) {
	var (
		code []byte
		err  error
	)

	switch in.Language {
	case proto.Language_LUAJIT:
		code, err = s.luaJITCompiler.Compile(ctx, in.Code)
	default:
		return nil, errors.NewWithMessage("unknown language", errors.ErrMethodNotImplemented)
	}

	if err != nil {
		return nil, errors.NewWithError(fmt.Errorf("compile: %w", err), errors.ErrInternalError)
	}

	return &service.CompileScriptOutput{
		Code: code,
	}, nil
}
